<template>
  <div class="scree-plot-chart">
     <div class="chart-title">
      <span class="title-text">{{ title }}</span>
      <!-- ✅ 单独导出按钮 -->
      <button
        v-if="showExportButton"
        size="mini"
        class="export-btn"
        @click="downloadImage"
        :title="`导出 ${title} 为 PNG`"
      >
        导出图片
      </button>
    </div>
    <div ref="correlationChart" class="chart-container"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'CorrelationChart',
  props: {
    title: {
      type: String,
      default: '相关性图'
    },
    rowData: {
      type: Object,
      required: true,
      default: () => ({})
    },
    latentVariableCount: {
      type: Number,
      default: 0
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '400px'
    },
    showExportButton: { type: Boolean, default: true }, // ✅ 控制导出按钮
  },
  data() {
    return {
      chart: null
    };
  },
  mounted() {
    this.initChart();
    window.addEventListener('resize', this.handleResize);
    // 确保在DOM更新后初始化图表
    this.$nextTick(() => {
      this.handleResize();
    });
  },
  beforeDestroy() {
    if (this.chart) this.chart.dispose();
    window.removeEventListener('resize', this.handleResize);
  },
  watch: {
    rowData: {
      handler() {
        this.$nextTick(() => {
          this.updateChart();
        });
      },
      deep: true
    },
    latentVariableCount() {
      this.$nextTick(() => {
        this.updateChart();
      });
    },
  },
  methods: {
    initChart() {
      if (!this.$refs.correlationChart) return;
      this.chart = echarts.init(this.$refs.correlationChart);
      // 确保在初始化后更新图表
      this.$nextTick(() => {
        this.updateChart();
      });
    },

    updateChart() {
      if (!this.chart || !this.rowData) {
        return;
      }

      // 准备数据
      const cvData = [];
      const testData = [];

      // CV数据（蓝色点）
      if (this.rowData.y_cv_true && this.rowData.y_cv_pred) {
        for (let i = 0; i < this.rowData.y_cv_true.length; i++) {
          const trueVal = this.rowData.y_cv_true[i];
          const predVal = this.rowData.y_cv_pred[i];
          // 处理预测值可能是数组的情况
          const predValue = Array.isArray(predVal) ? predVal[0] : predVal;
          cvData.push([trueVal, predValue]);
        }
      }

      // 验证集数据（红色点）
      if (this.rowData.y_test_true && this.rowData.y_test_pred) {
        for (let i = 0; i < this.rowData.y_test_true.length; i++) {
          const trueVal = this.rowData.y_test_true[i];
          const predVal = this.rowData.y_test_pred[i];
          // 处理预测值可能是数组的情况
          const predValue = Array.isArray(predVal) ? predVal[0] : predVal;
          testData.push([trueVal, predValue]);
        }
      }

      // 如果没有数据，显示提示信息
      if (cvData.length === 0 && testData.length === 0) {
        console.warn("相关性图数据为空");
        return;
      }

      // 计算数据范围用于绘制对角线
      const allData = [...cvData, ...testData];
      let minVal = Math.min(
        ...allData.map((point) => Math.min(point[0], point[1]))
      );
      let maxVal = Math.max(
        ...allData.map((point) => Math.max(point[0], point[1]))
      );

      // 扩大范围以便更好地显示
      const padding = (maxVal - minVal) * 0.1;
      minVal -= padding;
      maxVal += padding;

      // 计算回归线函数
      const calcRegression = (data, label) => {
        if (!data || data.length < 2) {
          console.log(`${label} 数据不足，无法计算回归线`);
          return [];
        }
        const n = data.length;
        let sumX = 0,
          sumY = 0,
          sumXY = 0,
          sumXX = 0;
        data.forEach(([x, y]) => {
          sumX += x;
          sumY += y;
          sumXY += x * y;
          sumXX += x * x;
        });
        const denominator = n * sumXX - sumX * sumX;
        if (Math.abs(denominator) < 1e-10) {
          console.log(`${label} 分母接近零，无法计算回归线`);
          return [];
        }
        const slope = (n * sumXY - sumX * sumY) / denominator;
        const intercept = (sumY - slope * sumX) / n;
        const regressionLine = [
          [minVal, slope * minVal + intercept],
          [maxVal, slope * maxVal + intercept],
        ];
        console.log(`${label} 回归线计算成功:`, {
          slope: slope.toFixed(4),
          intercept: intercept.toFixed(4),
        });
        return regressionLine;
      };

      console.log(
        "CV数据数量:",
        cvData.length,
        "Val数据数量:",
        testData.length
      );

      // 图表配置
      const option = {
        title: {
          text: `潜在变量数 ${this.latentVariableCount} 的相关性图`,
          left: "center",
          textStyle: {
            fontSize: 16,
          },
        },
        tooltip: {
          trigger: "item",
          formatter: function (params) {
            if (
              params.seriesName.includes("回归线") ||
              params.seriesName.includes("理想线")
            ) {
              return false; // 不显示回归线和理想线的tooltip
            }
            const type = params.seriesName;
            const [x, y] = params.data;
            return `${type}<br/>真实值: ${x.toFixed(4)}<br/>预测值: ${y.toFixed(
              4
            )}`;
          },
        },
        legend: {
          data: [
            "CV (校正集)",
            "Val (验证集)",
            "理想线 (y=x)",
            "CV回归线",
            "Val回归线",
          ],
          top: "8%",
        },
        grid: {
          left: "10%",
          right: "10%",
          bottom: "15%",
          top: "20%",
        },
        xAxis: {
          type: "value",
          name: "真实值 (Reference Value)",
          nameLocation: "center",
          nameGap: 30,
          min: minVal,
          max: maxVal,
          axisLabel: {
            formatter: function (value) {
              return value.toFixed(4);
            }
          }
        },
        yAxis: {
          type: "value",
          name: "预测值 (Predicted Value)",
          nameLocation: "center",
          nameGap: 50,
          min: minVal,
          max: maxVal,
          axisLabel: {
            formatter: function (value) {
              return value.toFixed(4);
            }
          }
        },
        series: [
          {
            name: "CV (校正集)",
            type: "scatter",
            data: cvData,
            symbolSize: 8,
            itemStyle: { color: "#3498db" },
          },
          {
            name: "Val (验证集)",
            type: "scatter",
            data: testData,
            symbol: "rect",
            symbolSize: 8,
            itemStyle: { color: "#e74c3c" },
          },
          {
            name: "理想线 (y=x)",
            type: "line",
            data: [
              [minVal, minVal],
              [maxVal, maxVal],
            ],
            lineStyle: { color: "#95a5a6", type: "dashed", width: 2 },
            itemStyle:{
              opacity:0
            },
            symbol: "none",
            legendHoverLink: false,
          },
          {
            name: "CV回归线",
            type: "line",
            data: calcRegression(cvData, "CV"),
            lineStyle: {
              color: "#1a5276",
              type: "dashed",
              width: 2,
              opacity: 0.7,
            },
            itemStyle:{
              opacity:0
            },
            symbol: "none",
            silent: true,
            legendHoverLink: false,
          },
          {
            name: "Val回归线",
            type: "line",
            data: calcRegression(testData, "Val"),
            lineStyle: {
              color: "#922b21",
              type: "dashed",
              width: 2,
              opacity: 0.7,
            },
            itemStyle:{
              opacity:0
            },
            symbol: "none",
            silent: true,
            legendHoverLink: false,
          },
        ],
      };

      this.chart.setOption(option, true);
    },

    handleResize() {
      if (this.chart) {
        // 设置容器尺寸
        if (this.$refs.correlationChart) {
          this.$refs.correlationChart.style.width = this.width;
          this.$refs.correlationChart.style.height = this.height;
        }
      }
    },

    /** 提供给父组件：获取 base64 */
    getChartBase64() {
      if (!this.chart) return null;
      return this.chart.getDataURL({
        type: 'png',
        pixelRatio: 2,
        backgroundColor: '#fff'
      });
    },

    /** ✅ 单独导出 PNG */
    downloadImage() {
      const base64 = this.getChartBase64();
      if (!base64) return;

      const ts = new Date();
      const pad = (n) => (n < 10 ? "0" + n : "" + n);
      const stamp = `${ts.getFullYear()}${pad(ts.getMonth() + 1)}${pad(ts.getDate())}-${pad(ts.getHours())}${pad(ts.getMinutes())}${pad(ts.getSeconds())}`;

      const name =
        (this.exportFileName && this.exportFileName.trim()) ||
        (this.title ? this.title.replace(/[\/\\:*?"<>|]/g, "_") : "chart");

      const a = document.createElement("a");
      a.href = base64;
      a.download = `${name}-${stamp}.png`;
      a.click();
    },
  }
};
</script>

<style scoped>
.scree-plot-chart {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.chart-title {
  position: relative;
  text-align: center;
  font-size: 16px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  padding: 0 10px;
}

.title-text {
  display: inline-block;
  padding: 0 40px; /* 给右边按钮留空间 */
}

.export-btn {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  padding: 2px 8px;
  background-color: #409eff;
  border: none;
  border-radius: 4px;
  color: #fff;
  cursor: pointer;
}

.export-btn:hover {
  background-color: #66b1ff;
}

.chart-container {
  flex: 1;
  min-height: 300px;
  width: 100%;
}
</style>